package com.rainbow.dynamic.repository;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;

import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.context.ApplicationEventPublisher;

import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.google.common.collect.Lists;
import com.rainbow.dynamic.utils.JsonUtils;

import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@Slf4j
public class NacosRouteDefinitionRepository implements RouteDefinitionRepository {

	//监听的dataId
	private String scgRouteDataId;
	//监听的dataId，归属的group
    private String scgRouteGroup;
    //事件发布者
    private ApplicationEventPublisher publisher;
    //nacos配置管理
    private NacosConfigManager nacosConfigManager;
    
    public NacosRouteDefinitionRepository(ApplicationEventPublisher publisher, 
    		NacosConfigManager nacosConfigManager,
    		String routeDataId,
    		String routeGroup) {
        this.publisher = publisher;
        this.nacosConfigManager = nacosConfigManager;
        this.scgRouteDataId = routeDataId;
        this.scgRouteGroup = routeGroup;
        addListener();
    }
	
	@Override
	public Flux<RouteDefinition> getRouteDefinitions() {
		try {
            String content = nacosConfigManager.getConfigService().getConfig(scgRouteDataId, scgRouteGroup,5000);
            List<RouteDefinition> routeDefinitions = getListByStr(content);
            return Flux.fromIterable(routeDefinitions);
        } catch (NacosException e) {
            log.error("getRouteDefinitions by nacos error", e);
        }
        return Flux.fromIterable(Lists.newArrayList());
	}
	
	/**
     * 添加Nacos监听
     */
    private void addListener() {
        try {
        	nacosConfigManager.getConfigService().addListener(scgRouteDataId, scgRouteGroup, new Listener() {
                @Override
                public Executor getExecutor() {
                    return null;
                }

                @Override
                public void receiveConfigInfo(String configInfo) {
                    publisher.publishEvent(new RefreshRoutesEvent(this));
                }
            });
        } catch (NacosException e) {
            log.error("nacos-addListener-error", e);
        }
    }
    
    private List<RouteDefinition> getListByStr(String content) {
        if (StringUtils.isNotEmpty(content)) {
        	try {
				return JsonUtils.jsonToList(content,RouteDefinition.class);
			}  catch (Exception e) {
				e.printStackTrace();
			}
        }
        return new ArrayList<>(0);
    }

	@Override
	public Mono<Void> save(Mono<RouteDefinition> route) {
		return null;
	}

	@Override
	public Mono<Void> delete(Mono<String> routeId) {
		return null;
	}

}
